﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Xml.Serialization;
using Minecraft_2D.Blocks;
using Minecraft_2D.Formulaires;
using Minecraft_2D.Formulaires.Menu;

namespace Minecraft_2D
{
    public class Map
    {
        #region Attributs;
        private int _length;
        private int _height;
        private List<List<Block>> _map;
        private bool IsNew;
        #endregion

        #region Constructeurs
        public Map()
        {
        }
        public Map(int length, int height, Minecraft2D f1)
        {
            IsNew = true;
            _length = length;
            _height = height;
            _map = new List<List<Block>>();
            //_map = new int[length, height];
            Random rnd = new Random();
            int blocks = BlocSet.GetSingleton().Percent;
            for (int i = 0; i < length; ++i)
            {
                List<Block> listL = new List<Block>();
                for (int j = 0; j < height; ++j)
                {
                    Block b = new Block() { Type = TypeBloc.Air };
                    listL.Add(b);
                }
                _map.Add(listL);
            }

            Block.Map = this;

            for (int i = 0; i < length; ++i)
            {
                for (int j = 0; j < height; ++j)
                {
                    _map[i][j].Position = new Point(i, j);
                    _map[i][j].Top = (j > 0) ? _map[i][j - 1] : null;
                    _map[i][j].Bottom = (j < height-1) ? _map[i][j + 1] : null;
                    _map[i][j].Left = (i > 0) ? _map[i - 1][j] : null;
                    _map[i][j].Right = (i < length-1) ? _map[i + 1][j] : null;
                }
            }
            for (int l = 0; l < _length; ++l)
            {
                List<int> listL = new List<int>();
                for (int h = rnd.Next(2,7); h < _height - 1; ++h)
                {
                    Point position = new Point(l, h);
                    int randBloc = rnd.Next(blocks);
                    bool trouve = false;
                    TypeBloc bloc;
                    Block map = _map[l][h];

                    //Gestion du pourcentage des blocs
                    int c = 0;
                    int p = 0;
                    while (!trouve && c < BlocSet.GetSingleton().Count)
                    {
                        p += BlocSet.GetSingleton()[c].Percent;
                        if (randBloc < p)
                            trouve = true;
                        else
                            c++;
                    }
                    randBloc = c;
                    bloc = (TypeBloc)randBloc;

                    TypeBloc b = BlocSet.GetSingleton()[bloc].OnNew(map);
                    //bloc = (b == TypeBloc.None) ? TypeBloc.Air : b;

                    //Enregistrement de l'Id
                    map.Type = (b == TypeBloc.None) ? TypeBloc.Air : b;
                }
                _map[l][_length - 1].Type = TypeBloc.BedRock;
            }
            //Pause.Save(this);
            IsNew = false;
        }
        #endregion

        #region Proprietes
        public int this[int length, int height]
        {
            get { return (int)_map[length][height].Type; }
            set
            {
                if(value != (int)TypeBloc.None)
                    _map[length][height].Type = (TypeBloc)value;
            }
        }

        public Block this[Point position]
        {
            get { return _map[position.X][position.Y]; }
            set
            {
                if (value.Type != TypeBloc.None)
                {
                    TypeBloc bloc = (IsNew) ?
                        BlocSet.GetSingleton()[value.Type].OnNew(this[position]) :
                            (BlocSet.GetSingleton()[value.Type].IsOK(this[position])) ?
                            value.Type :
                                TypeBloc.None;

                    if (bloc != TypeBloc.None)
                        _map[position.X][position.Y].Type = bloc;
                }
            }
        }

        public int Length
        {
            get { return _length; }
        }

        public int Height
        {
            get { return _height; }
        }
        #endregion

        #region Methodes
        #endregion
    }
}
